// 说明：Arch64汇编, 实现从1加到100的累加操作
// 作者: Hollson
// 日期: 2025/2/13

// 代码解释： 
// 1. 累加操作：使用 loop 标签的循环结构，从 1 加到 100，并将结果保存在 x20 寄存器中。 
// 2. 整数转字符串：使用 convert_loop 标签的循环结构，将累加结果逐位转换为 ASCII 字符，并保存到栈中。 
// 3. 字符串反转：由于转换后的字符串是倒序的，使用 reverse_loop 标签的循环结构将字符串反转。 
// 4. 打印结果：使用系统调用 write（系统调用号 64）将反转后的字符串打印到标准输出。 
// 5. 退出程序：使用系统调用 exit（系统调用号 93）正常退出程序，返回值为 0。 
 
.section .text 
.global _start 
 
_start:
    mov x19, #1      // 初始化计数器 i = 1 
    mov x20, #0      // 初始化累加器 sum = 0 
 
loop:
    add x20, x20, x19 // sum += i 
    add x19, x19, #1        // i++
    cmp x19, #100     // 比较 i 和 100 
    ble loop          // 当 i <= 100 时继续循环 
 
    // 将累加结果转换为字符串 
    sub sp, sp, #32   // 分配栈空间（32字节）
    mov x21, x20      // 保存累加结果到 x21 
    mov x22, #0       // 字符索引 
    mov x23, #10      // 除数 10 
 
convert_loop:
    udiv x25, x21, x23 // 商 
    msub x24, x25, x23, x21 // 余数 = x21 - (x25 * x23)
    add x24, x24, #'0' // 转换为 ASCII 字符 
    strb w24, [sp, x22] // 将字符保存到栈中 
    add x22, x22, #1    // 字符索引加 1 
    mov x21, x25       // 更新商为新的被除数 
    cmp x21, #0        // 检查商是否为 0 
    bne convert_loop   // 不为 0 则继续循环 
 
    // 反转字符串 
    mov x26, #0        // 起始索引 
    sub x27, x22, #1   // 结束索引（修正后的索引）
reverse_loop:
    cmp x26, x27       // 比较起始索引和结束索引 
    bge end_reverse    // 起始索引 >= 结束索引则结束反转 
    ldrb w28, [sp, x26] // 读取起始位置字符 
    ldrb w29, [sp, x27] // 读取结束位置字符 
    strb w29, [sp, x26] // 交换字符 
    strb w28, [sp, x27]
    add x26, x26, #1    // 起始索引加 1 
    sub x27, x27, #1    // 结束索引减 1 
    b reverse_loop      // 继续反转 
 
end_reverse:
    // 打印数字结果 
    mov x8, #64        // write 系统调用号 
    mov x0, #1         // 文件描述符（标准输出）
    mov x1, sp         // 字符串地址（栈指针）
    mov x2, x22        // 字符串长度 
    svc #0 
 
    // 打印换行符 
    mov x8, #64        // write 系统调用号 
    mov x0, #1         // 文件描述符 
    mov x1, sp         // 复用栈空间地址 
    mov w2, #0xA       // 换行符 ASCII 值 
    strb w2, [x1]      // 存入栈顶 
    mov x2, #1         // 打印1个字符 
    svc #0 
 
    // 恢复栈空间 
    add sp, sp, #32 
 
    // 系统调用退出 
    mov x8, #93        // exit 系统调用号 
    mov x0, #0         // 返回值 0 
    svc #0 

// 编译命令: aarch64-linux-gnu-as -g -o sum.o sum.s
// 链接命令: aarch64-linux-gnu-ld -o sum sum.o
// 运行命令: ./sum
